package org.dromara.web.CssUtil.payUtil;

import cn.hutool.core.util.XmlUtil;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;

import org.apache.poi.ss.formula.functions.T;
import org.dromara.web.CssUtil.payUtil.bean.AllocateAccountQueryOut;
import org.w3c.dom.Document;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
import cn.hutool.core.bean.BeanUtil;

/**
 * Created by Ricky on 2016/11/20.
 */
public class HttpUtils {

    public static final int SOCKET_TIME_OUT = 60000;
    public static final int CONNECT_TIME_OUT = 60000;
    public static final int CONNECTION_REQUEST_TIME_OUT = 60000;

    /**
     * 发送 post请求访问本地应用并根据传递参数不同返回不同结果
     */

    public static String post(String url, Map<String, String> map) {
        SSLContext sslContext = null;
        try {
            sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType)
                        throws CertificateException {
                    return true;
                }
            }).useProtocol("TLSv1.2").build();
        } catch (KeyManagementException e2) {
            e2.printStackTrace();
        } catch (NoSuchAlgorithmException e2) {
            e2.printStackTrace();
        } catch (KeyStoreException e2) {
            e2.printStackTrace();
        }
        // 信任域名
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .register("https", new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER))
                .build();
        BasicHttpClientConnectionManager connManager = new BasicHttpClientConnectionManager(socketFactoryRegistry);
        CloseableHttpClient httpclient = HttpClients.createMinimal(connManager);
        // 创建httppost
        HttpPost httppost = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(SOCKET_TIME_OUT)
                .setConnectTimeout(CONNECT_TIME_OUT)
                .setConnectionRequestTimeout(CONNECTION_REQUEST_TIME_OUT)
                .build();
        httppost.setConfig(requestConfig);
        // 创建参数队列
        List<NameValuePair> formparams = new ArrayList<>();

        Iterator it = map.keySet().iterator();
        while (it.hasNext()) {
            String key;
            String value;
            key = it.next().toString();
            value = map.get(key);

            formparams.add(new BasicNameValuePair(key, value));
        }

        UrlEncodedFormEntity uefEntity;
        try {
            uefEntity = new UrlEncodedFormEntity(formparams, Constants.CHARSET);
            httppost.setEntity(uefEntity);

            System.out.println("提交请求 " + httppost.getURI());
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                HttpEntity entity = response.getEntity();

                if (entity != null) {
                    return EntityUtils.toString(entity, Constants.CHARSET);
                }

                // 打印响应状态
                System.out.println(response.getStatusLine());
            } finally {
                response.close();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭连接,释放资源
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static <T> T post(String url, Object obj, Class<T> clazz) throws Exception {
        Map<String, String> param = new HashMap<String, String>();
        param.put("mchntCd", Constants.MCHNT_CD);
//        String test = XmlConvertUtil.bean2Xml(obj);
        Document dos = XmlUtil.beanToXml(obj);
        String st = XmlUtil.toStr(dos);
        param.put("message", FuiouRsaCipher.encryptByRsaPub(st, Constants.FY_PUBLIC_KEY, "GBK"));
        String res = HttpUtils.post(url, param);
        System.out.println(res);
        Document doc = XmlUtil.parseXml(res);
        String message = doc.getElementsByTagName("message").item(0).getTextContent();
        String sd = FuiouRsaCipher.decryptByRsaPri(message, Constants.MCHNT_PRIVATE_KEY, "GBK");
        Map<String, Object> xmlMap = XmlUtil.xmlToMap(sd);
        T out = BeanUtil.toBean(xmlMap,clazz);
        return out;
    }


    public static Map<String,Object>  postInfo(String url, Object obj) throws Exception {
        Map<String, String> param = new HashMap<String, String>();
        param.put("mchntCd", Constants.MCHNT_CD);
//        String test = XmlConvertUtil.bean2Xml(obj);
        Document dos = XmlUtil.beanToXml(obj);
        String st = XmlUtil.toStr(dos);
        param.put("message", FuiouRsaCipher.encryptByRsaPub(st, Constants.FY_PUBLIC_KEY, "GBK"));
        String res = HttpUtils.post(url, param);
        System.out.println(res);
        Document doc = XmlUtil.parseXml(res);
        String message = doc.getElementsByTagName("message").item(0).getTextContent();
        String sd = FuiouRsaCipher.decryptByRsaPri(message, Constants.MCHNT_PRIVATE_KEY, "GBK");
        Map<String, Object> xmlMap = XmlUtil.xmlToMap(sd);
        Map<String,Object> out2 = new HashMap<String,Object>();
        AllocateAccountQueryOut out = BeanUtil.toBean(xmlMap,AllocateAccountQueryOut.class);
        out2.put("AllocateAccountQueryOut", out);
        if (xmlMap.containsKey("result")) {
            Map<String, Object> accountInlist = (Map<String, Object>)
                ((Map<String, Object>) xmlMap.get("accountInlist")).get("accountInlist");
            System.out.println("账户ID: " + accountInlist.get("status"));
            xmlMap.put("status", accountInlist.get("status"));
            out2.put("status", accountInlist.get("status"));
        }

        return out2;
    }
}
